package remoteinfo;

import java.util.ArrayList;
import java.util.List;

import compiler.absyn.Constant;
import compiler.parse.DbParse;
import engine.planner.CreateIndexData;
import engine.planner.CreateTableData;
import engine.planner.CreateViewData;
import engine.planner.DeleteData;
import engine.planner.InsertData;
import engine.planner.ModifyData;
import engine.planner.QueryData;
import engine.query.Plan;
import engine.query.Scan;

import server.starDB;
import storage.record.Schema;
import storage.tx.Transaction;

public class RemoteDbParse {
	public RemoteDbParse() {
	}

	public ResultSet getResultSet(String cmd) {
		ResultSet rs = new ResultSet();
		DbParse dbparse = new DbParse("", System.out);
		int count = 0;
		int result = 0;
		try {
			Object o = dbparse.translate(cmd);
			if (o instanceof QueryData) {
				QueryData data = (QueryData) o;
				Transaction tx = new Transaction();
				Plan p = starDB.planner().createQueryPlan(data, tx);
				Scan s = p.open();
				while (s.next()) {
					count++;
				}
				int fs = data.fields.size();
				rs.fld = new String[fs];
				rs.num = count;
				int i = 0;
				for (String st : data.fields) {
					rs.fld[i++] = st;
				}
				rs.val = new String[fs][count];
				s.beforeFirst();
				count = 0;
				while (s.next()) {
					for (int j = 0; j < fs; j++) {
						Constant c = s.getVal(rs.fld[j]);
						rs.val[j][count] = c.toString();
					}
					count++;
				}
				tx.commit();
				rs.success = 1;// do query successfully
				rs.cmdtype = 0;
			} else if (o instanceof InsertData) {
				InsertData data = (InsertData) o;
				Transaction tx = new Transaction();
				result = starDB.planner().executeUpdate(data, tx);
				rs.updatenum = result>0?result:0;
				tx.commit();
			} else if (o instanceof CreateTableData) {
				CreateTableData data = (CreateTableData) o;
				Transaction tx = new Transaction();
				result = starDB.planner().executeUpdate(data, tx);
				rs.updatenum = result>0?result:0;
				tx.commit();
			} else if (o instanceof CreateViewData) {
				CreateViewData data = (CreateViewData) o;
				Transaction tx = new Transaction();
				result = starDB.planner().executeUpdate(data, tx);
				tx.commit();
			} else if (o instanceof CreateIndexData) {
				CreateIndexData data = (CreateIndexData) o;
				Transaction tx = new Transaction();
				result = starDB.planner().executeUpdate(data, tx);
				tx.commit();
			} else if (o instanceof DeleteData) {
				DeleteData data = (DeleteData) o;
				Transaction tx = new Transaction();
				result = starDB.planner().executeUpdate(data, tx);
				tx.commit();
			} else if (o instanceof ModifyData) {
				ModifyData data = (ModifyData) o;
				Transaction tx = new Transaction();
				result = starDB.planner().executeUpdate(data, tx);
				tx.commit();
			} else if (o == null) {
				result = -7;
				rs.errorMsg = dbparse.errormsg.msg;
				rs.success = 0;
			}
			if(result < 0){
				switch(result){
				case -1:rs.errorMsg="error: key dup error!";break;
				case -2:rs.errorMsg="error: not null error!";break;
				case -3:rs.errorMsg="error: fkey not exist!";break;
				case -4:rs.errorMsg="error: not satisfy the check condition!";break;
				case -5:rs.errorMsg="error: referenced key exist!";break;
				case -6:rs.errorMsg="error: foreign key check error!";break;
				default:break;
				}
				rs.success = 0;
			}else 
				rs.success = 1;
		} catch (Exception e) {
			rs.errorMsg = dbparse.errormsg.msg;
			rs.success = 0;
		}
		return rs;
	}
	public List<MetaInfo> getMetaInfos(){
		Transaction tx = new Transaction();
		List<String> tablenamelist = starDB.mdMgr().getTablenames(tx);
		List<MetaInfo> result = new ArrayList<MetaInfo>();
//		System.out.println("@@tablenamelist:"+tablenamelist);
		for(String tblname:tablenamelist){
			Schema sch = starDB.mdMgr().getTableInfo(tblname,tx).schema();
			result.add(new MetaInfo(tblname,sch));
		}
		return result;
		
	}
}
